package org.whuims.service.paragraph;

import org.apache.shiro.SecurityUtils;
import org.elasticsearch.common.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.result.ScoredPage;
import org.springframework.stereotype.Service;
import org.whuims.entity.Paragraph;
import org.whuims.entity.vo.ParagraphVo;
import org.whuims.repository.solr.SolrParagraphDao;
import org.whuims.service.account.ShiroDbRealm;

import java.text.ParseException;
import java.util.List;

/**
 * Created by zhongwei on 16/12/22.
 */
@Service
public class ParagraphSolrService {

    @Autowired
    private SolrParagraphDao solrParagraphDao;
    @Autowired
    private SolrTemplate solrTemplate;

    public Page<Paragraph> findBySearchFields(Pageable pageable, String searchFields) {
        return solrParagraphDao.findBySearchFields(pageable, searchFields);
    }

    public Page<Paragraph> findByTemplate(Pageable pageable, String keyword) {
        Query query = new SimpleQuery();
        query.setPageRequest(pageable);
        query.addCriteria(new Criteria("searchFields").expression(keyword));
        if (!getCurrentUserName().toLowerCase().equals("admin")) {
            query.addCriteria(new Criteria("userId").expression(String.valueOf(getCurrentUserId())));
        }
        solrTemplate.setSolrCore("docs_paragraph");
        ScoredPage<Paragraph> scoredPage = solrTemplate.queryForPage(query, Paragraph.class);
        return scoredPage;
    }

    public Page<Paragraph> findByTemplate(Pageable pageable, ParagraphVo paragraphVo) {
        Query query = null;
        try {
            query = buildQuery(paragraphVo);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        if (!getCurrentUserName().toLowerCase().equals("admin")) {
            query.addCriteria(new Criteria("userId").expression(String.valueOf(getCurrentUserId())));
        }
        query.setPageRequest(pageable);
        solrTemplate.setSolrCore("docs_paragraph");
        ScoredPage<Paragraph> scoredPage = solrTemplate.queryForPage(query, Paragraph.class);
        return scoredPage;
    }

    private Query buildQuery(ParagraphVo paragraphVo) throws ParseException {
        Query query = new SimpleQuery();
        String content = paragraphVo.getContent();
        Long docId = paragraphVo.getDocumentId();
        if (!Strings.isNullOrEmpty(content)) {
            query.addCriteria(new Criteria("content").expression(content));
        }
        if (docId != null) {
            query.addCriteria(new Criteria("documentId").expression(String.valueOf(docId)));
        }
        return query;
    }

    public void delete(List<String> paragraphIds) {
        solrTemplate.setSolrCore("docs_paragraph");
        solrTemplate.deleteById(paragraphIds);
    }

    public void delete(String paragraphId) {
        solrTemplate.setSolrCore("docs_paragraph");
        solrTemplate.deleteById(paragraphId);
    }

    public void deleteByDocumentId(Long documentId) {
        solrTemplate.setSolrCore("docs_paragraph");
        Query query = new SimpleQuery();
        query.addCriteria(new Criteria("documentId").expression(String.valueOf(documentId)));
        solrTemplate.delete(query);
    }

    /**
     * 取出Shiro中的当前用户Id.
     */
    private Long getCurrentUserId() {
        ShiroDbRealm.ShiroUser user = (ShiroDbRealm.ShiroUser) SecurityUtils.getSubject().getPrincipal();
        if (user == null) {
            return null;
        } else
            return user.id;
    }

    private String getCurrentUserName() {
        ShiroDbRealm.ShiroUser user = (ShiroDbRealm.ShiroUser) SecurityUtils.getSubject().getPrincipal();
        if (user == null)
            return null;
        else return user.loginName;
    }
}
